home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / s0ftpj / ICMPLIB_V1.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-17  |  10.6 KB  |  380 lines

  1. /*
  2. ########## ICMPLIB_V1.h ##################################################
  3. ######################## ICMP Tunneling Library ##########################
  4. ####################################################### by FuSyS #########
  5.  
  6.         V.1 - NO (C)1998 FuSyS - TCP/IP Tools Unlimited
  7.  
  8. **************************************************************************
  9. *  COSA:    Una libreria in standard C per sfruttare la possibilita' *
  10. *        offerta dal protocollo ICMP di inserire dati all'interno *
  11. *        del datagramma.                         *
  12. *                                     *
  13. *  CHI:        individui dotati di una conoscenza base di C e TCP/IP      *
  14. *        che siano abbastanza fantasiosi da trovare un uso per     *
  15. *        questo tipo di codice. Se non avete questi requisiti,      *
  16. *        per favore impadronitevene prima di tornare a questa     *
  17. *        lib.                             *
  18. *                                     *
  19. *  OS:        Linux 1.3.x e seguenti (raw sockets)             *
  20. *                                     *
  21. *  TNX:        Daemon9 e THC per i loro lavori                 *
  22. *                                                                        *
  23. *  LETTURE:    TCP/IP Illustrated Vol.1 di R.W.Stevens,          * 
  24. *        Project LOKI di Daemon9,                 *
  25. *        /usr/include/*.h                     *
  26. **************************************************************************
  27.  
  28. **************************************************************************
  29. * FUNZIONI                                 *
  30. *                                     *
  31. * void ICMP_init(void);         - inizializza il tunnel ICMP -         *
  32. *                                     *
  33. * int  ICMP_send(char *send_mesg, size_t mesglen, u_long dest_ip,     *
  34. *         int echo, int last);                     *
  35. *                - invia i dati nel datagramma -         *
  36. *         send_mesg :    dati da inviare                 *
  37. *         mesglen   :    lunghezza di send_data             *
  38. *         dest_ip   :    l'IP cui mandare il datagramma         *
  39. *         echo       :    1 se il datagramma contiene l'echo del     *
  40. *                server                     *
  41. *         last       :    1 se il datagramma e' l'ultimo di una      *
  42. *                serie                     *
  43. *                                                                        *
  44. * int  ICMP_sp_send(char *send_mesg, size_t mesglen, u_long dest_ip,     *
  45. *            u_long sp_ip);                     *
  46. *                - invia spoofando l'IP sorgente -     *
  47. *                send_mesg :    dati da inviare                          *
  48. *                mesglen   :    lunghezza di send_data                   *
  49. *                dest_ip   :    l'IP cui mandare il datagramma           *
  50. *         sp_ip       :    l'IP da spoofare             *
  51. *                                     *
  52. * int  ICMP_recv(char *recv_mesg, size_t mesglen, int echo);         *
  53. *                - riceve il datagramma -         *
  54. *        recv_mesg  :    dati in ricezione             *
  55. *        mesglen       :    lunghezza di recv_data             *
  56. *        echo       :    1 se riceviamo l'echo dal server     *
  57. *                                                                        *
  58. * void ICMP_reset(void); - resetta il tunnel ICMP -              *
  59. *                                                                        *
  60. *************************************************************************/
  61.  
  62. #include <string.h>
  63. #include <stdlib.h>
  64. #include <stdio.h>
  65. #include <signal.h>
  66. #include <errno.h>
  67. extern int errno;
  68.  
  69. #include <sys/types.h>
  70. #include <sys/time.h>
  71. #include <sys/param.h>
  72. #include <sys/socket.h>
  73. #include <sys/file.h>
  74. #include <netinet/in_systm.h>
  75. #include <netinet/in.h>
  76.  
  77. #ifdef linux
  78.   #include "linux_ip_icmp.h"
  79. #else
  80.   #include <netinet/ip_icmp.h>
  81.   #include <netinet/ip.h>
  82. #endif
  83.  
  84. #include <arpa/inet.h>
  85. #include <netdb.h>
  86.  
  87. #define ECHO_TAG       0xF001
  88. #define ECHO_LAST      0xF002
  89. #define REPLY           1
  90. #define LAST            1
  91. #define YEAH        1
  92. #define NOPE        0
  93.  
  94. #define ICMP_HDR            8          /* 8-byte ICMP header */
  95. #define IP_HDR                20    /* 20-byte IP header */
  96. #define MAXMESG               4096    /* dati max*/
  97. #define MAXPACKET             5004    /* dimensioni max del pacchetto */
  98.                                         /* ICMP_HDR + MAXMESG */
  99.  
  100.     int     sockfd ;
  101.     int     ip_spoof ;
  102.     u_long    spoof_addr ;
  103.     u_int      icmp_init = 1 ;
  104.     struct     sockaddr_in  clisrc;
  105.  
  106. /************************************************************************
  107. * Funzioni per DNS e checksum - sempre le solite :) niente di nuovo qui    *
  108. ************************************************************************/
  109.  
  110. u_long  nameResolve(char *hostname);
  111. char    *hostLookup(u_long in);
  112. u_short in_chksum(u_short *ptr, int nbytes);
  113.  
  114. u_long nameResolve(char *hostname)
  115. {
  116.   struct in_addr addr;
  117.   struct hostent *hostEnt;
  118.  
  119.   if((addr.s_addr=inet_addr(hostname)) == -1)
  120.   {
  121.     if(!(hostEnt=gethostbyname(hostname)))
  122.     {
  123.           fprintf(stderr,"Errore nella risoluzione del nome:`%s`\n",hostname);
  124.     exit(0);
  125.     }
  126.     bcopy(hostEnt->h_addr,(char *)&addr.s_addr,hostEnt->h_length);
  127.   }
  128.   return addr.s_addr;
  129. }
  130.     
  131. char *hostLookup(u_long in)
  132. {
  133.   char hostname[1024];
  134.   struct in_addr addr;
  135.   struct hostent *hostEnt;
  136.  
  137.  
  138.   bzero(&hostname,sizeof(hostname));
  139.   addr.s_addr = in;
  140.   hostEnt = gethostbyaddr((char *)&addr, sizeof(struct in_addr),AF_INET);
  141.  
  142.   if(!hostEnt)
  143.     strcpy(hostname,inet_ntoa(addr));
  144.   else
  145.     strcpy(hostname,hostEnt->h_name);
  146.  
  147.   return(strdup(hostname));
  148. }
  149.  
  150. u_short in_chksum(u_short *ptr, int nbytes)
  151. {
  152.   register long           sum;            /* assumes long == 32 bits */
  153.   u_short                 oddbyte;
  154.   register u_short        answer;         /* assumes u_short == 16 bits */
  155.  
  156.   /*
  157.    * Our algorithm is simple, using a 32-bit accumulator (sum),
  158.    * we add sequential 16-bit words to it, and at the end, fold back
  159.    * all the carry bits from the top 16 bits into the lower 16 bits.
  160.    */
  161.  
  162.   sum = 0;
  163.   while (nbytes > 1)
  164.   {
  165.     sum += *ptr++;
  166.     nbytes -= 2;
  167.   }
  168.  
  169.     /* mop up an odd byte, if necessary */
  170.   if (nbytes == 1)
  171.   {
  172.     oddbyte = 0;            /* make sure top half is zero */
  173.     *((u_char *) &oddbyte) = *(u_char *)ptr;   /* one byte only */
  174.     sum += oddbyte;
  175.   }
  176.  
  177.   /*
  178.    * Add back carry outs from top 16 bits to low 16 bits.
  179.    */
  180.  
  181.   sum  = (sum >> 16) + (sum & 0xffff);    /* add high-16 to low-16 */
  182.   sum += (sum >> 16);                     /* add carry */
  183.   answer = ~sum;          /* ones-complement, then truncate to 16 bits */
  184.  
  185.   return((u_short) answer);
  186. }
  187.  
  188. /************************************************************************
  189. ********************** Ed ora .... s_C_iotaim =;) ***********************
  190. ************************************************************************/
  191.     
  192. void ICMP_init(void)
  193. {
  194.     int spoof_opt = 1;
  195.  
  196.   if(icmp_init)
  197.   {
  198.     if (ip_spoof == NOPE) {
  199.     if((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0 ) {
  200.               fprintf(stderr, "Impossibile creare raw ICMP socket ");
  201.               exit(0);
  202.         }
  203.     }
  204.     if (ip_spoof == YEAH) {
  205.     if((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0 ) {
  206.                 fprintf(stderr, "Impossibile creare raw socket ");
  207.                 exit(0);
  208.     }
  209.     if(setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &spoof_opt,
  210.         sizeof(spoof_opt)) < 0 ) {
  211.         fprintf(stderr,"Impossibile creare IP Header ");
  212.         exit(0);
  213.     }
  214.     }
  215.     icmp_init = 0;
  216.   }
  217. }
  218.  
  219. void ICMP_reset(void)
  220. {
  221.   close(sockfd);
  222.   icmp_init = 1;
  223. }
  224.  
  225. int ICMP_send
  226. (char *send_mesg, size_t mesglen, u_long dest_ip, int echo, int last)
  227. {
  228.   int                   sparato;
  229.   struct tunnel {
  230.         struct icmp     icmp;
  231.         u_char          data[MAXMESG];
  232.   } icmp_pk;
  233.   int                   icmplen = sizeof(struct icmp);
  234.   int                   pach_dim;
  235.   struct sockaddr_in    dest;
  236.   int                   destlen;
  237.  
  238.   if(mesglen > MAXMESG)
  239.     return(-1);
  240.     
  241.   if(icmp_init)        
  242.     ICMP_init();
  243.  
  244.   destlen = sizeof(dest);
  245.   bzero((char *) &dest, destlen);
  246.   dest.sin_family       = AF_INET;
  247.   dest.sin_addr.s_addr  = dest_ip;
  248.  
  249.   pach_dim = mesglen + sizeof(struct icmp);
  250.   memset(&icmp_pk, 0, pach_dim);
  251.   icmp_pk.icmp.icmp_type = ICMP_ECHOREPLY;
  252.   bcopy(send_mesg, icmp_pk.icmp.icmp_data, mesglen);
  253.   icmp_pk.icmp.icmp_cksum = in_chksum((u_short *) &icmp_pk.icmp, 
  254.                 (sizeof(struct icmp)+mesglen));
  255.   if(echo) icmp_pk.icmp.icmp_seq = ECHO_TAG;
  256.   if(last) icmp_pk.icmp.icmp_seq = ECHO_LAST;
  257.  
  258.   if( (sparato = sendto(sockfd, &icmp_pk, pach_dim, 0, (struct sockaddr *)
  259.     &dest, destlen)) < 0 ) {
  260.             perror("RAW ICMP SendTo: ");
  261.         return(-1);
  262.   }
  263.   else if(sparato != pach_dim) {
  264.     perror("Dimensioni pacchetto IP errate: ");
  265.         return(-1);
  266.   }
  267.   return(sparato);
  268. }
  269.  
  270. int ICMP_sp_send(char *send_mesg, size_t mesglen, u_long dest_ip, u_long sp_ip)
  271. {
  272.   int                   sparato;
  273.   struct spoof {
  274.       struct ip    ip;
  275.       struct icmp      icmp;
  276.     u_char          data[MAXMESG];
  277.   } sp_pk;
  278.   int             iplen = sizeof(struct ip);
  279.   int            icmplen = sizeof(struct icmp);
  280.   int                   pach_dim;
  281.   struct sockaddr_in    dest;
  282.   int                   destlen;
  283.  
  284.   if(mesglen > MAXMESG)
  285.     return(-1);
  286.  
  287.   if(icmp_init)
  288.     ICMP_init();
  289.  
  290.   destlen = sizeof(dest);
  291.   bzero((char *) &dest, destlen);
  292.   dest.sin_family       = AF_INET;
  293.   dest.sin_addr.s_addr  = dest_ip;
  294.  
  295.   pach_dim = mesglen + sizeof(struct ip) + sizeof(struct icmp);
  296.   memset(&sp_pk, 0, pach_dim); 
  297.  
  298.   sp_pk.ip.ip_v = 4;
  299.   sp_pk.ip.ip_hl = 5;
  300.   sp_pk.ip.ip_len = htons(iplen + icmplen + mesglen);
  301.   sp_pk.ip.ip_ttl = 255;
  302.   sp_pk.ip.ip_p = IPPROTO_ICMP;
  303.   sp_pk.ip.ip_src.s_addr = sp_ip;
  304.   sp_pk.ip.ip_dst.s_addr = dest_ip;
  305.  
  306.   sp_pk.icmp.icmp_type = ICMP_ECHOREPLY;
  307.   bcopy(send_mesg, sp_pk.icmp.icmp_data, mesglen);
  308.   sp_pk.icmp.icmp_cksum = in_chksum((u_short *) &sp_pk.icmp,
  309.                 (sizeof(struct icmp)+mesglen));  
  310.  
  311.   if((sparato = sendto(sockfd, &sp_pk, pach_dim, 0, (struct sockaddr *)
  312.         &dest, destlen)) < 0 ) {
  313.         perror("RAW ICMP SendTo: ");
  314.         return(-1);
  315.   }
  316.   if(sparato != pach_dim) {
  317.         perror("Dimensioni pacchetto IP errate: ");
  318.         return(-1);
  319.   }
  320.   return(sparato);
  321. }
  322.  
  323. int ICMP_recv(char *recv_mesg, size_t mesglen, int echo)
  324. {
  325.   struct recv {
  326.     struct ip      ip;
  327.     struct icmp    icmp;
  328.     char        data[MAXMESG];
  329.   } rcv_pk;
  330.   int    pach_dim;          
  331.   int    accolto;
  332.   int   iphdrlen;
  333.   int   clilen = sizeof(clisrc);
  334.   
  335.   if(icmp_init)        
  336.     ICMP_init();
  337.   
  338.   while(1)
  339.   {
  340.     pach_dim = mesglen + sizeof(struct ip) + sizeof(struct icmp);
  341.     memset(&rcv_pk, 0, pach_dim);
  342.     if( (accolto = recvfrom(sockfd, &rcv_pk, pach_dim, 0, (struct
  343.     sockaddr *) &clisrc, &clilen)) < 0 )
  344.       continue;
  345.     
  346.     iphdrlen = rcv_pk.ip.ip_hl << 2;    
  347.     if(accolto < (iphdrlen + ICMP_MINLEN))
  348.       continue;
  349.     accolto -= iphdrlen;
  350.  
  351.    if(!echo){
  352.     if(!rcv_pk.icmp.icmp_id && !rcv_pk.icmp.icmp_code &&
  353.     rcv_pk.icmp.icmp_type == ICMP_ECHOREPLY && rcv_pk.icmp.icmp_seq !=
  354.     ECHO_TAG && rcv_pk.icmp.icmp_seq != ECHO_LAST)
  355.       break;
  356.    }
  357.    if(echo){
  358.     if(!rcv_pk.icmp.icmp_id && !rcv_pk.icmp.icmp_code &&
  359.     rcv_pk.icmp.icmp_type == ICMP_ECHOREPLY
  360.         && (rcv_pk.icmp.icmp_seq == ECHO_TAG || rcv_pk.icmp.icmp_seq ==
  361.     ECHO_LAST) )
  362.       break;
  363.    }
  364.   }
  365.      if(!echo){
  366.       accolto -= ICMP_HDR;
  367.       bcopy(rcv_pk.icmp.icmp_data, recv_mesg, accolto);
  368.       return(accolto);
  369.      }
  370.      if(echo){
  371.       if(rcv_pk.icmp.icmp_seq == ECHO_TAG) {
  372.             accolto -= ICMP_HDR;
  373.             bzero(recv_mesg, sizeof(recv_mesg));
  374.             bcopy(rcv_pk.icmp.icmp_data, recv_mesg, accolto);
  375.             return(accolto);
  376.       }
  377.         return(-666);
  378.      }
  379. }
  380.